<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MCP WebSocket Client</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 1200px;
            margin: 0 auto;
            padding: 20px;
            background-color: #f5f5f5;
        }
        .container {
            background: white;
            padding: 20px;
            border-radius: 8px;
            box-shadow: 0 2px 4px rgba(0,0,0,0.1);
        }
        .status {
            padding: 10px;
            margin: 10px 0;
            border-radius: 4px;
            font-weight: bold;
        }
        .connected { background-color: #d4edda; color: #155724; }
        .disconnected { background-color: #f8d7da; color: #721c24; }
        .messages {
            height: 400px;
            overflow-y: auto;
            border: 1px solid #ddd;
            padding: 10px;
            margin: 10px 0;
            background: #f9f9f9;
            font-family: monospace;
            font-size: 14px;
        }
        .message {
            margin: 5px 0;
            padding: 5px;
            border-left: 3px solid #007bff;
            background: white;
        }
        .message.sent {
            border-left-color: #28a745;
            background: #f8fff9;
        }
        .message.received {
            border-left-color: #007bff;
            background: #f8f9ff;
        }
        .message.error {
            border-left-color: #dc3545;
            background: #fff8f8;
        }
        .controls {
            display: grid;
            grid-template-columns: 1fr auto;
            gap: 10px;
            margin: 10px 0;
        }
        button {
            padding: 10px 20px;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 14px;
        }
        .btn-primary { background: #007bff; color: white; }
        .btn-success { background: #28a745; color: white; }
        .btn-danger { background: #dc3545; color: white; }
        .btn-secondary { background: #6c757d; color: white; }
        .tools {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 15px;
            margin-top: 20px;
        }
        .tool {
            border: 1px solid #ddd;
            border-radius: 4px;
            padding: 15px;
            background: white;
        }
        .tool h3 {
            margin-top: 0;
            color: #333;
        }
        .tool-input {
            width: 100%;
            padding: 8px;
            margin: 5px 0;
            border: 1px solid #ddd;
            border-radius: 4px;
        }
        select.tool-input {
            height: 40px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>MCP WebSocket Client</h1>
        <p>Connect to the SuperSocket MCP WebSocket server to test Model Context Protocol over WebSocket.</p>
        
        <div class="controls">
            <input type="text" id="serverUrl" value="ws://localhost:8080/mcp" placeholder="WebSocket server URL">
            <button id="connectBtn" class="btn-primary">Connect</button>
        </div>
        
        <div id="status" class="status disconnected">Disconnected</div>
        
        <div class="messages" id="messages"></div>
        
        <div class="controls">
            <input type="text" id="messageInput" placeholder="Send custom JSON-RPC message...">
            <button id="sendBtn" class="btn-success" disabled>Send</button>
        </div>
        
        <h2>Quick Actions</h2>
        <div style="display: flex; gap: 10px; flex-wrap: wrap;">
            <button id="initializeBtn" class="btn-secondary" disabled>Initialize</button>
            <button id="listToolsBtn" class="btn-secondary" disabled>List Tools</button>
            <button id="clearBtn" class="btn-danger">Clear Messages</button>
        </div>
        
        <h2>Tools</h2>
        <div class="tools">
            <div class="tool">
                <h3>Echo Tool</h3>
                <p>Echo back a message</p>
                <input type="text" class="tool-input" id="echoMessage" placeholder="Message to echo">
                <button onclick="callEchoTool()" class="btn-primary" disabled id="echoBtn">Call Echo</button>
            </div>
            
            <div class="tool">
                <h3>Math Tool</h3>
                <p>Perform basic math operations</p>
                <select class="tool-input" id="mathOperation">
                    <option value="add">Add</option>
                    <option value="subtract">Subtract</option>
                    <option value="multiply">Multiply</option>
                    <option value="divide">Divide</option>
                </select>
                <input type="number" class="tool-input" id="mathA" placeholder="First number" value="10">
                <input type="number" class="tool-input" id="mathB" placeholder="Second number" value="5">
                <button onclick="callMathTool()" class="btn-primary" disabled id="mathBtn">Calculate</button>
            </div>
            
            <div class="tool">
                <h3>Time Tool</h3>
                <p>Get current server time</p>
                <select class="tool-input" id="timeFormat">
                    <option value="iso">ISO Format</option>
                    <option value="local">Local Time</option>
                    <option value="utc">UTC Time</option>
                    <option value="unix">Unix Timestamp</option>
                </select>
                <button onclick="callTimeTool()" class="btn-primary" disabled id="timeBtn">Get Time</button>
            </div>
            
            <div class="tool">
                <h3>Web Info Tool</h3>
                <p>Get WebSocket connection info</p>
                <button onclick="callWebInfoTool()" class="btn-primary" disabled id="webinfoBtn">Get Info</button>
            </div>
        </div>
    </div>

    <script>
        let ws = null;
        let messageId = 1;
        let isInitialized = false;

        const status = document.getElementById('status');
        const messages = document.getElementById('messages');
        const connectBtn = document.getElementById('connectBtn');
        const sendBtn = document.getElementById('sendBtn');
        const messageInput = document.getElementById('messageInput');
        const serverUrl = document.getElementById('serverUrl');

        function addMessage(content, type = 'received') {
            const div = document.createElement('div');
            div.className = `message ${type}`;
            div.innerHTML = `<strong>${new Date().toLocaleTimeString()}</strong> - ${content}`;
            messages.appendChild(div);
            messages.scrollTop = messages.scrollHeight;
        }

        function updateStatus(connected) {
            status.textContent = connected ? 'Connected to MCP WebSocket Server' : 'Disconnected';
            status.className = `status ${connected ? 'connected' : 'disconnected'}`;
            
            connectBtn.textContent = connected ? 'Disconnect' : 'Connect';
            connectBtn.className = connected ? 'btn-danger' : 'btn-primary';
            
            sendBtn.disabled = !connected;
            document.getElementById('initializeBtn').disabled = !connected;
            document.getElementById('listToolsBtn').disabled = !connected || !isInitialized;
            
            // Tool buttons
            document.getElementById('echoBtn').disabled = !connected || !isInitialized;
            document.getElementById('mathBtn').disabled = !connected || !isInitialized;
            document.getElementById('timeBtn').disabled = !connected || !isInitialized;
            document.getElementById('webinfoBtn').disabled = !connected || !isInitialized;
        }

        function connect() {
            if (ws && ws.readyState === WebSocket.OPEN) {
                ws.close();
                return;
            }

            try {
                ws = new WebSocket(serverUrl.value, ['mcp']);
                
                ws.onopen = () => {
                    updateStatus(true);
                    addMessage('Connected to MCP WebSocket server', 'received');
                };
                
                ws.onmessage = (event) => {
                    try {
                        const data = JSON.parse(event.data);
                        addMessage(`Received: <code>${JSON.stringify(data, null, 2)}</code>`, 'received');
                        
                        // Check if this is an initialize response
                        if (data.result && data.result.protocolVersion) {
                            isInitialized = true;
                            updateStatus(true);
                            addMessage('MCP session initialized successfully!', 'received');
                        }
                    } catch (e) {
                        addMessage(`Received (raw): ${event.data}`, 'received');
                    }
                };
                
                ws.onclose = () => {
                    updateStatus(false);
                    isInitialized = false;
                    addMessage('Disconnected from server', 'error');
                };
                
                ws.onerror = (error) => {
                    addMessage(`WebSocket error: ${error}`, 'error');
                };
            } catch (e) {
                addMessage(`Connection error: ${e.message}`, 'error');
            }
        }

        function sendMessage(message) {
            if (ws && ws.readyState === WebSocket.OPEN) {
                const msgStr = typeof message === 'string' ? message : JSON.stringify(message);
                ws.send(msgStr);
                addMessage(`Sent: <code>${msgStr}</code>`, 'sent');
                return true;
            }
            return false;
        }

        function initialize() {
            const message = {
                jsonrpc: "2.0",
                id: messageId++,
                method: "initialize",
                params: {
                    protocolVersion: "2024-11-05",
                    capabilities: {},
                    clientInfo: {
                        name: "MCP WebSocket Test Client",
                        version: "1.0.0"
                    }
                }
            };
            sendMessage(message);
        }

        function listTools() {
            const message = {
                jsonrpc: "2.0",
                id: messageId++,
                method: "tools/list"
            };
            sendMessage(message);
        }

        function callEchoTool() {
            const message = {
                jsonrpc: "2.0",
                id: messageId++,
                method: "tools/call",
                params: {
                    name: "echo",
                    arguments: {
                        message: document.getElementById('echoMessage').value || "Hello WebSocket MCP!"
                    }
                }
            };
            sendMessage(message);
        }

        function callMathTool() {
            const message = {
                jsonrpc: "2.0",
                id: messageId++,
                method: "tools/call",
                params: {
                    name: "math",
                    arguments: {
                        operation: document.getElementById('mathOperation').value,
                        a: parseFloat(document.getElementById('mathA').value),
                        b: parseFloat(document.getElementById('mathB').value)
                    }
                }
            };
            sendMessage(message);
        }

        function callTimeTool() {
            const message = {
                jsonrpc: "2.0",
                id: messageId++,
                method: "tools/call",
                params: {
                    name: "time",
                    arguments: {
                        format: document.getElementById('timeFormat').value
                    }
                }
            };
            sendMessage(message);
        }

        function callWebInfoTool() {
            const message = {
                jsonrpc: "2.0",
                id: messageId++,
                method: "tools/call",
                params: {
                    name: "webinfo",
                    arguments: {}
                }
            };
            sendMessage(message);
        }

        // Event listeners
        connectBtn.addEventListener('click', connect);
        sendBtn.addEventListener('click', () => {
            const input = messageInput.value.trim();
            if (input) {
                try {
                    const message = JSON.parse(input);
                    sendMessage(message);
                } catch (e) {
                    sendMessage(input);
                }
                messageInput.value = '';
            }
        });

        messageInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                sendBtn.click();
            }
        });

        document.getElementById('initializeBtn').addEventListener('click', initialize);
        document.getElementById('listToolsBtn').addEventListener('click', listTools);
        document.getElementById('clearBtn').addEventListener('click', () => {
            messages.innerHTML = '';
        });

        // Initialize UI
        updateStatus(false);
    </script>
</body>
</html>